#include <iostream>
using std::cout;
using std::endl;

void test0(){
    //const在*左边
    //叫做常量指针
    //本质是一个指针，一个指向常量的指针
    //不能直接改变指向的值，但是可以改变指向
    int number = 7, number2 = 8;
    const int * p = &number;
    /* *p = 5; */
    p = &number2;

    int const * p2 = &number;
    /* *p2 = 5; */
    p2 = &number2;
}

void test1(){
    int number = 7, number2 = 8;
    //const在*号右边，表示指针常量
    //p是一个指针，但是这里它的本质是一个常量
    //（指针类型的常量）
    //可以直接修改所指的值
    //不能改变指向
    //常量的性质是施加在指针上
    int * const p  = &number;
    *p = 5;
    /* p = &number2; */

    //双重const的指针保证了既不能改变所指值，
    //又不能改变指向
    const int * const p2 = &number;
    /* *p2 = 5; */
    /* p2 = &number2; */
}

//数组指针 本质是指针，是一个指向数组的指针
void test2(){
    int arr[5] = {1,2,3,4,5};
    //这里的5不能省略，表示的是p需要去申请多大的空间
    int (*p)[5] = &arr;
    for(int i = 0; i < 5; ++i){
        cout << (*p)[i] << endl;
    }
}

//指针数组  本质是数组，其中的元素都是指针
void test3(){
    int num = 100,num2 = 200, num3 = 300;
    int *p = &num;
    int *p2 = &num2;
    int *p3 = &num3;
    int * arr[3] = {p,p2,p3};
    for(int i = 0; i < 3; ++i){
        cout << *arr[i] << endl;
    }
}

//函数指针 一个指针指向函数
int add(int x,int y){
    return x + y;
}

int (*p)(int,int) = add;
void test4(){
    cout << p(6,7) << endl;
}


//指针函数  一个返回类型为指针的函数
int Num = 760;
int* f(){
    int * p = &Num;
    return p;
}
void test5(){
    cout << *f() << endl;
}

int main(void){
    /* test0(); */
    /* test2(); */
    /* test3(); */
    /* test4(); */
    test5();
    return 0;
}
